<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>03_计算属性和监视</title>
    </head>
    <body>
        <!--
      1. 计算属性
        在computed属性对象中定义计算属性的方法
        在页面中使用{{方法名}}来显示计算的结果
      2. 监视属性:
        通过通过vm对象的$watch()或watch配置来监视指定的属性
        当属性变化时, 回调函数自动调用, 在函数内部进行计算
      3. 计算属性高级:
        通过getter/setter实现对属性数据的显示和监视
        计算属性存在缓存, 多次读取只执行一次getter计算
    -->
        <div id="app">
            姓: <input type="text" placeholder="First Name" v-model="firstName" /><br />
            名: <input type="text" placeholder="Last Name" v-model="lastName" /><br />
            姓名1: <input type="text" placeholder="Full Name1" v-model="fullName1" /><br />
            姓名2: <input type="text" placeholder="Full Name2" v-model="fullName2" /><br />
            <p>{{count}}</p>
            <button @click="update">count+1</button>
            <p>{{person.age}}</p>
            <button @click="updateAge">age数据变化</button>
        </div>

        <script type="text/javascript" src="../js/vue.js"></script>
        <script type="text/javascript">
            new Vue({
                el: '#app',
                // 数据代理：data,methods,witch等产生的属性方法都放在this上，他们只是代理作用，是私有属性
                data: {
                    firstName: '李',
                    lastName: '沛华',
                    count: 0,
                    person:{
                      age:18,
                    }
                },
                methods: {
                    update() {
                        // console.log(this)
                        // 改变this.count的才会自动渲染数据
                        this.count = this.count + 1
                    },
                    updateAge(){
                      this.person.age=this.person.age+1
                    }
                },

                computed: {
                    // 计算属性
                    // 有两种写法
                    // 1.只读的计算属性 2.只读的计算属性

                    fullName1() {
                        // 只可读,是一个函数，调用这个函数时，得到函数返回值
                        return this.firstName + ' ' + this.lastName
                    },
                    // 可读可写
                    fullName2: {
                        // 读
                        get() {
                            return this.firstName + ' ' + this.lastName
                        },
                        // 写
                        set(val) {
                            // split以空格分隔，返回是一个数组，解构数组
                            let [firstName, lastName] = val.split(' ')
                            this.firstName = firstName
                            this.lastName = lastName
                            // 修改了数据，会自动渲染数据，不需要返回值的
                            // return this.firstName + ' ' + this.lastName
                        },
                    },
                },
                // 监听数据变化
                watch: {
                    // 监听数据，一开始不会执行，之后数据发生了变化会执行
                    // 1.写要监听的数据，这种写法不会一上来调用
                    // count: function (newValue, preValue) {
                    //     console.log(newValue, preValue)
                    // },
                    //2. 一上来就监听数据变化
                    count: {
                        handler(newVal, preVal) {
                            console.log(newVal, preVal)
                        },
                        // 一上来就监听数据
                        immediate: true,
                    },
                    // 监听对象,是浅层对比，地址没有变化，需要深度对比加一个deep:true
                    person:{
                      handler(newVal,preVal){
                        console.log(newVal,preVal);
                      },
                      deep:true,
                      immediate:true
                    }
                },
            })
        </script>
    </body>
</html>
